package export

import (
	"errors"
	"fmt"
	"log"
	"os"
	"os/exec"
	"path/filepath"

	"gitee.com/chuanjinge/go-container/container/overlay2"
)

// 导出容器为镜像tar包
func ExportAsTar(containerId string) error {
	containerPath := overlay2.GetContainerDirMerged(containerId)

	if _, err := os.Stat(containerPath); err != nil && os.IsNotExist(err) {
		return errors.New("找不到容器目录")
	}

	// tar包放到images下

	// 指定目标目录和归档文件名
	targetDir := "/data/tinydocker/image"
	tarFileName := fmt.Sprintf("%s.tar", containerId)

	// 确保目标目录存在
	err := os.MkdirAll(targetDir, 0755)
	if err != nil {
		log.Printf("Error creating target directory: %v\n", err)
		return err
	}

	// 构建最终的 tar 文件路径
	tarFilePath := filepath.Join(targetDir, tarFileName)

	// 创建一个临时文件用于存储 tar 归档
	tmpFile, err := os.CreateTemp("", "archive-*.tar")
	if err != nil {
		log.Printf("Error creating temporary file: %v\n", err)
		return err
	}
	defer os.Remove(tmpFile.Name()) // 清理临时文件

	// 使用 tar 命令创建归档文件
	// 将要打包的文件作为参数传递给 tar 命令
	/**
	"tar"：命令名称，即调用的程序是 tar。
	"-czf"：选项组合，具体含义如下：
		-c：创建新的归档文件。
		-z：通过 gzip 压缩归档文件。
		-f：指定归档文件的名称（这里是 imageTar）。
	imageTar：这是输出的 tar 文件的路径和名称。
	"-C"：改变工作目录到给定的路径（这里是 containerPath），然后添加文件到归档中。
	containerPath：指定的工作目录路径，即源目录。
	"."：表示从当前工作目录（由 -C 指定）开始打包所有内容
	*/
	cmd := exec.Command("tar", "-czf", tmpFile.Name(), "-C", containerPath, ".")
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	cmd.CombinedOutput()
	cmd.Dir = containerPath // 设置工作目录
	// 执行 tar 命令
	err = cmd.Run()
	if err != nil {
		fmt.Printf("Error running tar command: %v\n", err)
		return err
	}

	// 将临时文件移动到目标位置
	err = os.Rename(tmpFile.Name(), tarFilePath)
	if err != nil {
		fmt.Printf("Error moving tar file to target directory: %v\n", err)
		return err
	}

	fmt.Printf("Tar file created and moved successfully to: %s\n", tarFilePath)
	return nil
}
